# -*- coding: utf-8 -*-
"""
国力的计算目前包含: 基础(by_base)、大臣(by_minister)、珍宝(by_harem)
和后宫(by_harem)四个子系统以及全局 buff 。当添加新的子系统(例如 foo)
时需对 `IndicatorsAdapter` 添加 `by_foo` 属性，并修改`update` 方法中的求和公式为
`` ...
   zip(self.by_base, self.by_minister, self.by_tresure, self.by_harem, self.by_foo) ...
`` 。
"""
import zope.component

import pyshare.bll.events as events
import pyshare.const.enums.role_buff as role_buff
from pyshare.utils.game_log.log_param import LogParam
from pyshare.const.enums.activity import *
from common.service_config import get_action_id


class IndicatorsMixin(object):
    __slots__ = ()

    def log_change(self, old_comprehensive, new_comprehensive, remark=None):
        try:
            from pyshare.utils.game_log.game_log_define import IndicatorsLog
            # 国力涨幅日志
            mark = '{}国力涨幅'.format(remark) if remark else '国力涨幅'
            IndicatorsLog.log_game(log_param=LogParam(rid=self._record.RoleGuid,
                                                      scene=get_action_id(),
                                                      remark=mark,
                                                      reserve={}),
                                   old_val=old_comprehensive,
                                   new_val=new_comprehensive)
        except:
            pass

    @staticmethod
    def apply_on_buff(base, *args):
        from app.area.component.buff_component import CalculateManager
        return CalculateManager.get_new_value(base, a_v=args[0], a_p=args[1])

    def update(self, remark=None):
        """根据加成值更新有效值。"""
        old_comprehensive = self.comprehensive
        role_id = self._record.RoleGuid

        # 对子系统提供的商、农、政、军求和
        b, a, p, m = map(sum, zip(
            self.by_base, self.by_minister, self.by_harem, self.by_prince
        ))
        from pyshare.redis_cache.area.buff_redis_cache import RoleBuffCache
        buff_cache = RoleBuffCache()
        buff_dict = buff_cache.get_buff_list(role_id, role_buff.AllIndicators)

        self.business = self.apply_on_buff(b, *buff_dict[role_buff.BuffType.Business])
        self.agricultural = self.apply_on_buff(a, *buff_dict[role_buff.BuffType.Agricultural])
        self.political = self.apply_on_buff(p, *buff_dict[role_buff.BuffType.Political])
        self.military = self.apply_on_buff(m, *buff_dict[role_buff.BuffType.Military])

        # 综合国力
        self.comprehensive = (
            self.business +
            self.agricultural +
            self.political +
            self.military +
            self.harem +
            self.prince
        )
        self.save()

        event = events.IndicatorsChanged(
            role_id=role_id,
            indicators=self)
        zope.component.handle(event)
        try:
            # 记录日志
            self.log_change(old_comprehensive, self.comprehensive, remark=remark)
        except:
            pass
        return self.comprehensive

    def apply_addition(self, target, addition, remark=None):
        """应用加成。

        :param target: 子系统名 (base | minister | harem | etc.)
        :param addition: [商, 农, 政, 军]
        :param remark: 加成来源 (使用资质果|大臣升级|etc.)
        """
        old_comprehensive = self.comprehensive
        by = 'by_' + target
        setattr(self, by, map(
            sum, zip(getattr(self, by), addition)
        ))
        new_comprehensive = self.update(remark=remark)
        self.comprehensive_change_activity(old_comprehensive, new_comprehensive)

    def apply_base_addition(self, addition, remark=None):
        self.apply_addition('base', addition, remark=remark)

    def apply_minister_addition(self, addition, remark=None):
        self.apply_addition('minister', addition, remark=remark)

    def apply_harem_addition(self, addition, remark=None):
        self.apply_addition('harem', addition, remark=remark)

    def apply_prince_addition(self, addition, remark=None):
        self.apply_addition('prince', addition, remark=remark)

    def comprehensive_change_activity(self, old_comprehensive, new_comprehensive):
        # 国力涨幅活动事件
        rank_event = events.ActivityProgressChanged(
            role_id=self._record.RoleGuid,
            a_type=ActivityType.Comprehensive,
            add_value=new_comprehensive - old_comprehensive
        )
        zope.component.handle(rank_event)

    @property
    def silvers_taxation(self):
        from pyshare.redis_cache.area.buff_redis_cache import RoleBuffCache
        buff_cache = RoleBuffCache()
        buff = buff_cache.get_buff(self._record.RoleGuid, role_buff.BuffType.ConscriptSilver)
        return self.apply_on_buff(self.business, buff['AddValue'], buff['AddPercent'])

    @property
    def grains_taxation(self):
        from pyshare.redis_cache.area.buff_redis_cache import RoleBuffCache
        buff_cache = RoleBuffCache()
        buff = buff_cache.get_buff(self._record.RoleGuid, role_buff.BuffType.ConscriptGrain)
        return self.apply_on_buff(self.agricultural, buff['AddValue'], buff['AddPercent'])

    @property
    def soldiers_taxation(self):
        from pyshare.redis_cache.area.buff_redis_cache import RoleBuffCache
        buff_cache = RoleBuffCache()
        buff = buff_cache.get_buff(self._record.RoleGuid, role_buff.BuffType.ConscriptSoldier)
        return self.apply_on_buff(self.political, buff['AddValue'], buff['AddPercent'])

    def asdict(self):
        return {
            'Comprehensive': self.comprehensive,
            'Agricultural': self.agricultural,
            'Business': self.business,
            'Political': self.political,
            'Military': self.military,
            'Harem': self.harem,
            'Prince': self.prince,

            'ByBase': self.by_base,
            'ByMinister': self.by_minister,
            'ByHarem': self.by_harem,
            'ByPrince': self.by_prince,

            'SilversTaxation': self.silvers_taxation,
            'GrainsTaxation': self.grains_taxation,
            'SoldiersTaxation': self.soldiers_taxation,

            'ArtifactScore': self.artifact_score,
            'WearArtifactScore': self.wear_artifact_score,
        }
